//! \file memory_utils.c

#include "memory_utils.h"

//------------------------------------------------------------------------------

TBGError ReadStr(addr_t addr, unsigned int len, char *read_str) {
    TBGError ret = 0;
    CHECK_RET(addr, INVALID_ADDR, exit_point, ret);
    CHECK_DBG_ERR(len, ZERO_LENGTH);
    CHECK_DBG_ERR(read_str, NULL_PTR);

	CHECK_CALL(ReadByteData(addr, read_str, len), exit_point, ret);

exit_point:
    return ret;
}

//------------------------------------------------------------------------------

#ifndef USE_PTRACE

//------------------------------------------------------------------------------

TBGError ReadData(addr_t addr, void *vptr, unsigned int len_in_addrs) {
    TBGError ret = 0;
    CHECK_RET(addr, INVALID_ADDR, exit_point, ret);
    CHECK_DBG_ERR(len_in_addrs, ZERO_LENGTH);
    CHECK_DBG_ERR(vptr, NULL_PTR);

    unsigned int i = 0;
    for(i = 0; i < len_in_addrs; ++i)
        ((addr_t*) vptr)[i] = ((addr_t*) addr)[i];

exit_point:
    return ret;
}

//------------------------------------------------------------------------------

TBGError ReadByteData(addr_t addr, void *vptr, unsigned int len) {
    TBGError ret = 0;
    CHECK_RET(addr, INVALID_ADDR, exit_point, ret);
    CHECK_DBG_ERR(len, ZERO_LENGTH);
    CHECK_DBG_ERR(vptr, NULL_PTR);
    
    unsigned int i = 0;
    for(i = 0; i < len; ++i) 
        ((char*) vptr)[i] = ((char*) addr)[i];

exit_point:
    return ret;
}

//------------------------------------------------------------------------------

#else //#ifdef USE_PTRACE

//------------------------------------------------------------------------------

TBGError ReadData(addr_t addr, void *vptr, unsigned int len_in_addrs) {
    TBGError ret = 0;
    CHECK_DBG_ERR(sizeof(addr_t) == sizeof(long), SIZES_DIFFERS);
    ptrace_session* pps = PtraceGetSetSession(NULL);
    CHECK_DBG_ERR(pps, CANNOT_GET_STORED_ARG);

    CHECK_CALL(PtraceReadData(pps, addr, vptr, len_in_addrs), exit_point, ret);

exit_point:
    return ret;
}

//------------------------------------------------------------------------------

TBGError ReadByteData(addr_t addr, void *vptr, unsigned int len) {
    TBGError ret = 0;
    CHECK_DBG_ERR(sizeof(addr_t) == sizeof(long), SIZES_DIFFERS);
    ptrace_session* pps = PtraceGetSetSession(NULL);
    CHECK_DBG_ERR(pps, CANNOT_GET_STORED_ARG);

    CHECK_CALL(PtraceReadByteData(pps, addr, vptr, len), exit_point, ret);
    
exit_point:
    return ret;
}

//------------------------------------------------------------------------------

ptrace_session* PtraceGetSetSession(ptrace_session *psession) {
    static ptrace_session *psession_;
    if(psession)
        psession_ = psession;
    CHECK_DBG_ERR(psession, CANNOT_GET_STORED_ARG);
    return psession_;
}


//------------------------------------------------------------------------------

#endif //USE_PTRACE

